package com.sfl.api_backend.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sfl.api_backend.constant.HttpCode;
import com.sfl.api_backend.entity.SecurityUser;
import com.sfl.api_backend.entity.Users;
import com.sfl.api_backend.service.ILoginService;
import com.sfl.api_backend.service.IUsersService;
import com.sfl.api_backend.utils.Api.RestResult;
import com.sfl.api_backend.utils.Jwt.JwtUtil;
import com.sfl.api_backend.utils.RandomID;
import com.sfl.api_backend.utils.Redis.RedisUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Author szc
 * @create 2023/2/3 10:23
 */
@Service
public class LoginServiceImpl implements ILoginService {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private IUsersService usersService;

    @Override
    public RestResult signIn(Users users) {
        try {
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(users.getEmail(),users.getPassword())
            );
            if(Objects.isNull(authentication)){
                return RestResult.error(HttpCode.UNAUTHORIZED, "用户名或密码错误");
            }
            // 生成jwt
            SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();
            Users tmpUser = securityUser.getUsers();
            tmpUser.setPassword(null);
            String userJson = JSON.toJSONString(tmpUser);
            String Jwt = JwtUtil.createJWT(userJson);

            redisUtil.set("SignInUser:" + tmpUser.getUserId(), userJson, 60 * 60 *3000L);

            Map<String, Object> map = new HashMap<>();

            map.put("token", Jwt);
            map.put("userData", tmpUser);

            return RestResult.success(map);

        } catch (Exception e) {
            e.printStackTrace();
            return RestResult.error(HttpCode.NOT_IMPLEMENTED, "系统异常");
        }
    }
    
    @Override
    public RestResult signOut() {
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();
        Integer userId = securityUser.getUsers().getUserId();
        redisUtil.del("SignInUser:" + userId);
        return RestResult.success();
    }

    @Override
    public RestResult signUp(Users users) {
        Wrapper<Users> wrapper = new LambdaQueryWrapper<>();
        ((LambdaQueryWrapper<Users>) wrapper).eq(Users::getEmail, users.getEmail());

        var listUser = usersService.getOne(wrapper);

        if (Objects.nonNull(listUser)) {
            return RestResult.error(HttpCode.NOT_IMPLEMENTED, "该邮箱已被注册");
        }

        if (users.getPassword().length() < 6) {
            return RestResult.error(HttpCode.NOT_IMPLEMENTED, "密码长度不能小于6位");
        }

        if (users.getPassword().length() > 16) {
            return RestResult.error(HttpCode.NOT_IMPLEMENTED, "密码长度不能大于16位");
        }

        // random id length 6
        users.setUserId(RandomID.getRandomID());

        users.setPassword(new BCryptPasswordEncoder().encode(users.getPassword()));
        usersService.save(users);
        return RestResult.success();
    }

}
